#include "gameroom.h"
#include "ui_gameroom.h"
#include "gameselect.h"
#include "widget.h"
#include <QPainter>
#include <QPixmap>
#include <QTimer>
#include <QPushButton>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QShortcut>
#include <QString>
#include <QMediaPlayer>
#include <QLabel>
#include <QDateTime>
//第三个页面
GameRoom::GameRoom(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::GameRoom)
{
    ui->setupUi(this);
    this->setFixedSize(800,600);




    //15.初始化贪吃蛇  //现只有单个
    snakeList.push_back(QRectF(this->width()*0.5,this->height()*0.5,SnakeNodeWidth,SnakeNodeHeight));

    //有一个多一截
    MoveUp();
    MoveUp();


    //创建食物
    CreateFood();

    //这个就是为什么蛇能够移动。
    timer = new QTimer(this);
    QMessageBox* FailMess = new QMessageBox(this);
    connect(timer,&QTimer::timeout,[=]()
    {
        if(checkFail())
        {
            timer->stop();
            sound->stop();
            QMediaPlayer *player = new QMediaPlayer;
            // 设置音频文件
            player->setMedia(QUrl("qrc:/res/gameover.wav"));

            // 播放音频
            player->play();

            // 创建一个计时器来控制播放时长
            QTimer::singleShot(3000, [=]() {
              // 3000 毫秒后停止播放
              player->stop();
            });

            //按钮的字体太大了
            FailMess->setFixedSize(400,400);
            QFont font("方正舒体",50);
            FailMess->setFont(font);
            FailMess->setText(QString("Game Over!!!"));
            FailMess->move(this->width()*0.25,this->height()*0.5);

            QPushButton *retGame = new QPushButton;
            QFont btnFont("方正舒体",25);
            retGame->setFont(btnFont);
            retGame->setText("重新开始");
            QPushButton *retGameHall = new QPushButton;
            retGameHall->setFont(btnFont);
            retGameHall->setText("返回主界面");

            FailMess->addButton(retGame,QMessageBox::AcceptRole);
            FailMess->addButton(retGameHall,QMessageBox::RejectRole);

            FailMess->show();
            FailMess->exec();


            AddScoreToFile();
            if(FailMess->clickedButton() == retGame)
            {
                this->close();
                GameRoom *gameRoom = new GameRoom;
                gameRoom->setGeometry(this->geometry());
                gameRoom->show();
                gameRoom->setTimeout(moveTimeout);

            }
            else
            {
                this->close();
                Widget* gamehall = new Widget;
                gamehall->show();
            }


        }
//        //食物的数量
        int cnt = 1;

        if(snakeList.front().intersects(foodRect))
        {
            CreateFood();
            cnt++;
            QSound::play(":res/eatfood.wav");
        }

        while(cnt--)
        {
            switch(moveDirect)
            {
                case SnakeDirect::UP:
                MoveUp();
                break;
                case SnakeDirect::DOWN:
                MoveDown();
                break;
                case SnakeDirect::LEFT:
                MoveLeft();
                break;
                case SnakeDirect::RIGHT:
                MoveRight();
                break;
            default:
                return;
                break;
            }
        }
        snakeList.pop_back();//删除最后一个节点  为啥？？  蛇的移动，前面的头新加，后面的尾巴去掉。

        update();
    });

    //17开始游戏，暂停游戏
    QPushButton *startBtn = new QPushButton(this);
    QPushButton *stopBtn = new QPushButton(this);

    startBtn->move(650,100);
    stopBtn->move(650,170);

    startBtn->setText("开始");
    stopBtn->setText("暂停");

    QFont  font("华文行楷",30);
    QString btnStyle = ("QPushButton {"
                        "border: 2px solid #8f8f91;"        // 设置边框
                        "border-radius: 15px;"              // 设置圆角半径
                        "background-color: #d1d1d1;"        // 设置背景颜色
                        "padding: 5px 10px;"                // 设置内边距
                        "}"
                        "QPushButton:hover {"
                        "background-color: #c0c0c0;"        // 设置鼠标悬停时的背景颜色
                        "}"
                        "QPushButton:pressed {"
                        "background-color: #a9a9a9;"        // 设置按钮按下时的背景颜色
                        "}");
    startBtn->setFont(font);
    startBtn->setStyleSheet(btnStyle);

    stopBtn->setFont(font);
    stopBtn->setStyleSheet(btnStyle);


    //开始
    //old
//    connect(startBtn,&QPushButton::clicked,[=]()
//    {
//        isGameStart = true;
//        timer->start(moveTimeout);
//        sound = new QSound(":res/Trepak.wav");
//        sound->play();
//        sound->setLoops(-1);

//    });

    //new
    connect(startBtn,&QPushButton::clicked,[=]()
    {
        //要对isGameStart进行判断
        if(!isGameStart)
        {
            isGameStart = true;
            timer->start(moveTimeout);
            sound = new QSound(":res/Trepak.wav");
            sound->play();
            sound->setLoops(-1);
        }
        else
        {
            qDebug()<<"游戏已经开始了";
        }
    });

    //暂停
    //old
//    connect(stopBtn,&QPushButton::clicked,[=]()
//    {
//        isGameStart = false;
//        timer->stop();
//        sound->stop();
//    });

    //new
    connect(stopBtn, &QPushButton::clicked, [=]()
    {
        if (isGameStart) {
            // 游戏已经开始，允许暂停
            isGameStart = false;

            // 检查定时器是否已经启动
            if (timer && timer->isActive()) {
                timer->stop();
            }

            // 检查音效是否正在播放
            if (sound && sound->isFinished() == false) {
                sound->stop();
            }
        }
        else {
            // 游戏尚未开始，不做任何处理
            qDebug() << "游戏未开始，无需暂停";
        }
    });

    //18.方向控制
    QPushButton *up = new QPushButton(this);
    QPushButton *down = new QPushButton(this);
    QPushButton *left =  new QPushButton(this);
    QPushButton *right = new QPushButton(this);


    //按钮的焦点设置，将按钮不设焦点
//    up->setFocusPolicy(Qt::NoFocus);
//    down->setFocusPolicy(Qt::NoFocus);
//    left->setFocusPolicy(Qt::NoFocus);
//    right->setFocusPolicy(Qt::NoFocus);

//    startBtn->setFocusPolicy(Qt::NoFocus);
//    stopBtn->setFocusPolicy(Qt::NoFocus);


    //快捷键设置 //在这个位置不生效
//    up->setShortcut(QKeySequence(Qt::Key_Up));
//    down->setShortcut(QKeySequence(Qt::Key_Down));
//    left->setShortcut(QKeySequence(Qt::Key_Left));
//    right->setShortcut(QKeySequence(Qt::Key_Right));

    //按钮位置设置
    up->move(675,300);
    down->move(675,400);
    left->move(625,350);
    right->move(725,350);

    //字体设置
    up->setFont(font);
    down->setFont(font);
    left->setFont(font);
    right->setFont(font);

    up->setText("↑");
    up->setStyleSheet(btnStyle);
    down->setText("↓");
    down->setStyleSheet(btnStyle);
    left->setText("←");
    left->setStyleSheet(btnStyle);
    right->setText("→");
    right->setStyleSheet(btnStyle);

     //快捷键设置 //在这位置生效
    up->setShortcut(QKeySequence(Qt::Key_Up));
    down->setShortcut(QKeySequence(Qt::Key_Down));
    left->setShortcut(QKeySequence(Qt::Key_Left));
    right->setShortcut(QKeySequence(Qt::Key_Right));


    //上移按键
    connect(up,&QPushButton::clicked,[=]()
    {        
        if(moveDirect != SnakeDirect::DOWN)
        {
            moveDirect = SnakeDirect::UP;
        }
    });

    //下移按键
    connect(down,&QPushButton::clicked,[=]()
    {
        if(moveDirect != SnakeDirect::UP)
        {
            moveDirect = SnakeDirect::DOWN;
        }
    });

    //左移按键
    connect(left,&QPushButton::clicked,[=]()
    {
        if(moveDirect != SnakeDirect::RIGHT)
        {
            moveDirect = SnakeDirect::LEFT;
        }
    });
    //右移按键
    connect(right,&QPushButton::clicked,[=]()
    {
        if(moveDirect != SnakeDirect::LEFT)
        {
            moveDirect = SnakeDirect::RIGHT;
        }
    });

//    if(checkFail())
//        this->close();

    //19.退出游戏
    QPushButton *exitBtn = new QPushButton(this);
    exitBtn->setText("退出游戏");
    exitBtn->move(610,500);
    exitBtn->setFont(font);
    exitBtn->setStyleSheet(btnStyle);

    exitBtn->setFocusPolicy(Qt::NoFocus);

    QMessageBox *message = new QMessageBox(this);
    QPushButton *ok = new QPushButton("是");
    QPushButton *cancel = new QPushButton("否");

    //向QMessageBox中添加按钮
    message->addButton(ok,QMessageBox::AcceptRole);
    message->addButton(cancel,QMessageBox::RejectRole);

    //设置标题和内容
    message->setWindowTitle("退出游戏");
    message->setText("是否退出游戏?");

    connect(exitBtn,&QPushButton::clicked,[=]()
    {
        if (sound && sound->isFinished() == false) {
            sound->stop();
        }
        if (timer && timer->isActive()) {
            timer->stop();
        }
        message->show();
        //事件轮询，需要通过用户的输入在对message进行关闭
        message->exec();
        Gameselect* gameselect = new Gameselect;
        QSound::play(":res/clicked.wav");


        //看选择的按钮做出相应的操作
        if(message->clickedButton() == ok)
        {
            this->close();
            gameselect->show();
        }
        else
        {
            message->close();
            sound->play();
            timer->start(moveTimeout);
        }
    });

//    while(1)
//    {
//        qDebug()<<this->geometry();
//        qDebug()<<this->frameGeometry();
//    }


}

GameRoom::~GameRoom()
{
    delete ui;
}

void GameRoom::paintEvent(QPaintEvent *event)
{
    (void) event;
    QPainter painter(this);

    QPixmap pix;
    pix.load(":res/game_room.png");
    painter.drawPixmap(0,0,600,600,pix);//左边的游戏区域

    pix.load(":res/bg1.png");

//    painter.drawPixmap(600,0,200,600,pix);最下边有部分没有绘制完，这是因为还有状态栏这些，所以没有绘制完
    painter.drawPixmap(600,0,200,700,pix);

    //14.绘制蛇：  蛇头 +  身体  +  尾巴

    //蛇头：  上 下 左 右
    if(moveDirect == SnakeDirect::UP)
    {
        pix.load(":res/up.png");
    }
    else if(moveDirect == SnakeDirect::DOWN)
    {
        pix.load(":res/down.png");
    }
    else if(moveDirect == SnakeDirect::LEFT)
    {
        pix.load(":res/left.png");
    }
    else
        pix.load(":res/right.png");

    auto snakeHead = snakeList.front();
    painter.drawPixmap(snakeHead.x(),snakeHead.y(),snakeHead.width(),snakeHead.height(),pix);

    //14.蛇身
    pix.load(":res/Bd.png");
    for(int i=1;i<snakeList.size()-1;i++)
    {
        auto node = snakeList.at(i);
        painter.drawPixmap(node.x(),node.y(),node.width(),node.height(),pix);
    }

    //14.蛇的尾巴
    auto snakeTail = snakeList.back();
    painter.drawPixmap(snakeTail.x(),snakeTail.y(),snakeTail.width(),snakeTail.height(),pix);

    //16.食物的绘制
    pix.load(":res/food.bmp");
    painter.drawPixmap(foodRect.x(),foodRect.y(),foodRect.width(),foodRect.height(),pix);


    //20.绘制积分
    pix.load(":res/sorce_bg.png");
    painter.drawPixmap(this->width()*0.80,this->height()*0.06,90,40,pix);

    QPen pen;
    pen.setColor(Qt::black);
    painter.setPen(pen);
    QFont font("方正舒体",22);
    painter.setFont(font);
    //调整都合适的位置
    painter.drawText(this->width()*0.87,this->height()*0.11,QString("%1").arg(snakeList.size()));


    //21.绘制游戏失败效果
//    if(checkFail())
//    {
//       pen.setColor(Qt::red);
//       painter.setPen(pen);
//       QFont font("方正舒体",50);
//       painter.setFont(font);

//       painter.drawText(this->width()*0.25,this->height()*0.5,QString("Game Over!!!"));
//       timer->stop();
//       sound->stop();

//       QMediaPlayer *player = new QMediaPlayer;
//       // 设置音频文件
//       player->setMedia(QUrl("qrc:/res/gameover.wav"));

//       // 播放音频
//       player->play();

//       // 创建一个计时器来控制播放时长
//       QTimer::singleShot(3000, [=]() {
//           // 3000 毫秒后停止播放
//           player->stop();
//       });




    //24.添加分数到文件中
    //这种绘制的方式是一直更新，文件中的分数。
//    int score = snakeList.size();

//    QFile file("D:/Users/lenovo/Desktop/Snake/snakeGame/1.txt");
//    if(file.open(QFile::Append | QFile::Text))
//    {
//        QTextStream out(&file);
//        int num = score;
//        out << num;

//        file.close();
//    }


    //test

}

//向上移动
void GameRoom::MoveUp()
{
    QPointF newPosLeftTop;// 左上角坐标
    QPointF newPosRightBottom; //右下角坐标

    auto oldPos = snakeList.front();//头

    int headX = oldPos.x();
    int headY = oldPos.y();

    if(headY-(SnakeNodeWidth) < 0)//穿墙的情况
    {
        newPosLeftTop = QPointF(headX,this->height()-SnakeNodeHeight);
    }
    else //墙内移动
    {
        newPosLeftTop = QPointF(headX,headY-SnakeNodeHeight);
    }

    newPosRightBottom = newPosLeftTop + QPointF(SnakeNodeWidth,SnakeNodeHeight);
    snakeList.push_front(QRectF(newPosLeftTop,newPosRightBottom));
    //??  这里使用push_front 与 为什么不 pop_back 删除为节点呢？
}

void GameRoom::MoveDown()
{

    QPointF newPosLeftTop;// 左上角坐标
    QPointF newPosRightBottom; //右下角坐标

    auto oldPos = snakeList.front();//头

    int headX = oldPos.x();
    int headY = oldPos.y();


    if(headY+(2*SnakeNodeWidth) > this->height())
    {
        newPosLeftTop = QPointF(headX,0);
    }
    else
    {
        //1.
        newPosLeftTop = QPointF(headX,headY+SnakeNodeHeight);
        //2.
//        leftTop = snakeNode.bottomLeft();
    }

    newPosRightBottom = newPosLeftTop + QPointF(SnakeNodeWidth,SnakeNodeHeight);
    snakeList.push_front(QRectF(newPosLeftTop,newPosRightBottom));

}

void GameRoom::MoveLeft()
{
    QPointF newPosLeftTop;// 左上角坐标
    QPointF newPosRightBottom; //右下角坐标

    auto oldPos = snakeList.front();//头

    int headX = oldPos.x();
    int headY = oldPos.y();

    if(headX-(SnakeNodeWidth) < 0)
    {
        newPosLeftTop = QPointF(600-SnakeNodeWidth,headY);
    }
    else
    {
        newPosLeftTop = QPointF(headX - SnakeNodeWidth,headY);
    }

    newPosRightBottom = newPosLeftTop + QPointF(SnakeNodeWidth,SnakeNodeHeight);
    snakeList.push_front(QRectF(newPosLeftTop,newPosRightBottom));
}

void GameRoom::MoveRight()
{
    QPointF newPosLeftTop;// 左上角坐标
    QPointF newPosRightBottom; //右下角坐标

    auto oldPos = snakeList.front();//头

    int headX = oldPos.x();
    int headY = oldPos.y();

    if(headX+(2*SnakeNodeWidth) > 600)
    {
        newPosLeftTop = QPointF(0,headY);

    }
    else {
        newPosLeftTop = oldPos.topRight();
    }

    newPosRightBottom = newPosLeftTop + QPointF(SnakeNodeWidth,SnakeNodeHeight);
    snakeList.push_front(QRectF(newPosLeftTop,newPosRightBottom));

}


//13.检查游戏是否结束
bool GameRoom::checkFail()
{
    auto snakeNode = snakeList.front();
    for(int i=1;i<snakeList.size();i++)
    {
        if(snakeList.at(i) == snakeNode)
            return true;

    }
    return false;
}
//bool GameRoom::checkFail()
//{
//    for(int i=0;i<snakeList.size();i++)
//    {
//        for(int j=i+1;j<snakeList.size()-1;j++)
//             if(snakeList.at(i) == snakeList.at(j))
//                return true;

//    }
//    return false;
//}

//创建食物
void GameRoom::CreateFood()
{
    foodRect = QRectF(qrand() % (600 / SnakeNodeWidth) * SnakeNodeHeight,
                      qrand() % (this->height() / SnakeNodeHeight)*SnakeNodeWidth,
                      SnakeNodeWidth,
                      SnakeNodeHeight);
}

void GameRoom::AddScoreToFile()
{
    int score = snakeList.size();
    QFile file("score.txt");

    QDateTime gameTime = QDateTime::currentDateTime();
    QString endGameTime = gameTime.toString("yyyy-MM-dd HH:mm:ss");
    endGameTime += "  得分为: ";

    if(file.open(QFile::Append | QFile::Text))
    {
        QTextStream out(&file);
        int num = score;
        out << endGameTime << num << endl;

    }

    file.close();
}


